# pragma once
# include<map>
# include<functional>
# include<Arduino.h>
# include<ArduinoJson.h>
# include "message.hpp"

using namespace std;

const String ACTION_NOT_FOUND = "NOT_FOUND";

typedef function<void(String, JsonArray, JsonObject)> RpcCall;

class RpcHanlder {
    private:
    
    std::map<String, RpcCall > handlers;
    
    public:
    
    void regist(String action, RpcCall func) {
        handlers[action] = func;
    }

    bool valid_action(String action) {
        return handlers.find(action) != handlers.end();
    }

    void call(Message message) {
        //Serial.println("calling:");
        //message.print();
        String target = message.get<String>(TARGET);
        if (target == TARGET_BROCAST || target == WORKER_NAME) {
            String action = message.get<String>(ACTION);
            auto itr = handlers.find(action);
            if (itr != handlers.end()) {
                (itr->second)(itr->first, message.get<JsonArray>(ARGS), message.get<JsonObject>(KW_ARGS));
            } else {
                not_found(message.to_string());
            }
        } else {
            // target miss
        }
    }

    static void not_found(String action) {
        //Serial.printf("action(%s) not found.\n", action.c_str());
    }
}rpc_handler;
